// 四、手写实现MyPromise源码
// 要求：尽可能还原Promisek中的每一个API, 并通过注释的方式描述思路和原理。

/* 
    1. Promise 就是一个类 在执行这个类的时候 需要传递一个执行器进去 执行器会立即执行
    2. Promise 中有三种状态 分别为 成功: fulfilled 失败: rejected 等待： pending
      pending -> fulfilled
      pending -> rejected
      一旦状态确定就不可更改
    3. resolve和reject函数是用来更改状态的
      resolve: fulfilled
      reject: rejected
    4. then方法内部做的事情就是判断状态
        如果状态是成功 则调用成功的回调函数
        如果状态是失败 则调用失败的回调函数
        then方法是被定义在原型对象中的
    5. then成功回调有一个参数 表示成功之后的值 then失败回调有一个失败的原因
    6. then方法是可以被同一个promise对象多次调用的，还可以分别是同步执行，也可以是异步方法
    7. then方法是可以被链式调用的，后面then方法的回调函数拿到的是上一个then方法的回调函数的返回值
*/

const MyPromise = require('./common/myPromise')

let myPromise = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('成功消息')
    }, 2000)
    // reject('失败消息')
    // throw new Error('executor error')
})

function other() {
    return new MyPromise((resolve, reject) => {
        resolve('other')
        // reject('other err')
    })
}

let p1 = myPromise
    .then(value => {
        // console.log('成功1: ', value)
        throw new Error('失败消息')
        // console.log('p1: ', p1);
        // p1.then(res => {
        //     console.log('res: ', res);
        //     return 'p1'
        // })
        // return p1
    // }, err => {
    //     console.log('失败1: ', err)
    //     return 111
    })
    .catch(err => {
        console.log('失败：', err.message);
    })
    .finally(() => {
        console.log('finally');
        return myPromise
    })
    .then(value => {
        console.log('成功2: ', value)
        let o = other()
        return o
        // throw new Error('成功后异常')
    }, err => {
        console.log('失败2: ', err)
    })
    .catch(err => {
        console.log('失败22：', err);
    })
    .then(value => {
        console.log('成功3: ', value)
    }, err => {
        console.log('失败3: ', err)
    })

MyPromise.all([myPromise, other()])
.then(result => {
    console.log('MyPromise.all: ', result);
})


MyPromise.resolve(myPromise)
    .then(res => {
        console.log('MyPromise.resolve: ', res);
    })
